#include "SList.h"


void SLTPrint(SLTNode* phead)
{
    SLTNode* cur = phead;

    while (cur)
    {
        printf("%d ", cur->data);
        cur = cur->next;
    }
    printf("\n");
}

SLTNode* BuySLTNode(SLTDataType x)
{
    SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
    if (NULL == newnode)
    {
        perror("malloc fail");
        exit(-1);
    }
    
    newnode->data = x;
    newnode->next =NULL;
    return newnode;
}

void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
    assert(pphead);

    SLTNode* newnode = BuySLTNode(x);

    if(NULL == *pphead)
    {
        *pphead = newnode;
    }
    else
        {
            SLTNode* tail = *pphead;
            while (tail->next)
            {
                tail = tail->next;
            }
            tail->next = newnode;
        }
}

void SLTPopBack(SLTNode** pphead)
{
    assert(pphead);
    assert(*pphead);

    SLTNode* cur = *pphead;
    SLTNode* tmp = NULL;
    if (NULL == cur->next)
    {
        free(*pphead);
        *pphead = NULL;
    }
    else
    {
        while (cur->next->next)
        {
            cur = cur->next;
        }
        free(cur->next);
        cur->next = NULL;
    }
}

void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
    assert(pphead);

    SLTNode* newnode = BuySLTNode(x);
    newnode->next = *pphead;
    *pphead = newnode;

}

void SLTPopFront(SLTNode** pphead)
{
    assert(pphead);
    assert(*pphead);

    SLTNode* tmp = *pphead;
    *pphead = (*pphead)->next;
    free(tmp);
    tmp = NULL;
}

SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{
    
    SLTNode* cur = phead;
    while (cur)
    {
        if (x == cur->data)
            return cur;
        cur = cur->next;
    }

    return NULL;

}

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
    assert(pphead);
    assert(pos);
    assert(*pphead);

    SLTNode* newnode = BuySLTNode(x);
    if (pos == *pphead)
    {
        newnode->next = *pphead;
        *pphead = newnode;
    }
    else 
        {
            SLTNode* cur = *pphead;
            while (pos != cur->next)
            {
                cur = cur->next;
            }
            newnode->next = cur->next;
            cur->next = newnode;
        }
}


void SLTErase(SLTNode** pphead, SLTNode* pos)
{
    assert(pphead);
    assert(pos);
    assert(*pphead);

    if (pos == *pphead)
    {
        SLTNode* tmp = (*pphead)->next;
        free(*pphead);
        *pphead = tmp;
    }
    else 
        {
            SLTNode* cur = *pphead;
            while (pos != cur->next)
            {
                cur = cur->next;
            }

            SLTNode* tmp = cur->next;
            cur->next = cur->next->next;
            free(tmp);
            tmp = NULL;
        }

}

void SLTInsertAfter(SLTNode* head, SLTNode* pos, SLTDataType x)
{
    assert(head);
    assert(pos);

    SLTNode* newnode = BuySLTNode(x);
    newnode->next = pos->next;
    pos->next = newnode;
}

void SLTEraseAfter(SLTNode* pos)
{
    assert(pos);
    assert(pos->next);

    SLTNode* tmp = pos->next;
    pos->next =pos->next->next;
    free(tmp);
    tmp = NULL;
}

void SLTDestroy(SLTNode** pphead)
{
    assert(pphead);
    assert(*pphead);

    SLTNode* cur = *pphead;
    while (cur)
    {
        SLTNode* tmp = cur;
        cur = cur->next;
        free(tmp);
        tmp = NULL;
    }
    *pphead = NULL;
}